﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Lilium.Collections
{
    public static class EnumerableExtensions
    {
        public static T Single<T>(this IEnumerable<T> source, Func<Exception> empty, Func<Exception> many)
        {
            if (source == null) throw new ArgumentNullException("source");
            if (empty == null) throw new ArgumentNullException("empty");
            if (many == null) throw new ArgumentNullException("many");

            using (var enumerator = source.GetEnumerator())
                if (enumerator.MoveNext())
                {
                    var item = enumerator.Current;
                    if (enumerator.MoveNext())
                        throw many();
                    else
                        return item;
                }
                else throw empty();
        }

        public static IEnumerable<T> Singleton<T>(T value)
        {
            yield return value;
        }

        public static IEnumerable<T> Append<T>(this IEnumerable<T> source, T item)
        {
            if (source == null) throw new ArgumentNullException("source");

            foreach (var current in source)
                yield return current;

            yield return item;
        }
    }
}